// CmdLineParser.h: interface for the CCmdParser class.
// 
// Copyright (c) Pavel Antonov, 2002
//
// This code is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CMDLINEPARSER_H__BE51B7B0_4BC9_44F1_9B88_DF33BE4280DF__INCLUDED_)
#define AFX_CMDLINEPARSER_H__BE51B7B0_4BC9_44F1_9B88_DF33BE4280DF__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


namespace parsers
{

/*! \brief A Command line parser

\par Example of strings
 /Key1 /Key2 -Key3:Val3 -Key4:"Val 4-with/spaces/and-delimeters" /Key5:Val5
 /Key:"" is equal to /Key: and is equal to /Key
 /Key is equal to -Key

  If getCaseSensitive is false (by default), all keys are made lowercase.

\par Examples of use:
\code
 CCmdParser parser(_T("/Key1 /Key2: -Key3:Val3 -Key4:\"Val 4-with/spaces/and-delimeters\" /Key5:Val5"));
 ASSERT(parser.HasKey("Key1") == true);
 ASSERT(parser.HasKey("Key10") == false);
 ASSERT(parser.HasVal("Key2") == false);
 parser.GetVal("Key1") -> []; (empty string)
 parser.GetVal("Key2") -> []; (empty string)
 parser.GetVal("Key3") -> [Val3];
 parser.GetVal("Key4") -> [Val 4-with/spaces/and-delimeters];

 CCmdParser::POSITION pos = parser.getFirst();	
 CString sKey, sVal;

  while(!parser.isLast(pos)) 
  {
		parser.getNext(pos, sKey, sVal);
		printf("Key: [%s], Val: [%s]");
 }
\endcode
*/
class CCmdParser 
{
public:
	typedef std::map<CString, CString> ValueMap;
public:

	CCmdParser(LPCTSTR sCmdLine = NULL, bool bCaseSensitive = false);
	virtual ~CCmdParser();

	LPCTSTR GetDelimeters() const		{	return m_sDelimeters;};
	LPCTSTR GetValueSep() const		{	return m_sValueSep;};
	LPCTSTR GetQuotes() const			{	return m_sQuotes;};

	void SetDelimeters( LPCTSTR szDelimeters )	{	m_sDelimeters = szDelimeters;};
	void SetValueSep( LPCTSTR szValueSep )	{	m_sValueSep = szValueSep;};
	void SetQuotes( LPCTSTR szQuotes )			{	m_sQuotes = szQuotes;};

	bool Parse(LPCTSTR sCmdLine);

	LPCTSTR GetCmdLine() const { return m_sCmdLine; }

	void SetCaseSensitive(bool bSensitive) { m_bCaseSensitive = bSensitive; }
	bool GetCaseSensitive() const { return m_bCaseSensitive; }

	// TRUE if "Key" present in command line
	bool HasKey(LPCTSTR sKey, CString& sVal) const;
	// Is "key" present in command line and have some value
	bool HasVal(LPCTSTR sKey) const;
	// Returns value if value was found or NULL otherwise
	LPCTSTR GetVal(LPCTSTR sKey) const;
	// Returns true if value was found
	bool GetVal(LPCTSTR sKey, CString& sValue) const;

	
	ValueMap::const_iterator begin()	{	return m_ValueMap.begin();};
	ValueMap::const_iterator end()		{	return m_ValueMap.end();};
	const ValueMap& GetVals() const		{ return m_ValueMap; }

private:
	ValueMap::const_iterator FindKey(LPCTSTR sKey) const;

private:
	CString m_sCmdLine;
	ValueMap	m_ValueMap;

	bool m_bCaseSensitive;

	CString m_sDelimeters;
	CString m_sValueSep;
	CString m_sQuotes;
};

};

#endif // !defined(AFX_CMDLINEPARSER_H__BE51B7B0_4BC9_44F1_9B88_DF33BE4280DF__INCLUDED_)
